package com.example.demo.utils;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description
 * @Author chenhuiyu
 */
public class HBaseOperations {
    public static Configuration configuration;
    public static Connection connection;
    public static Admin admin;

    public static void main(String[] args) throws IOException {
        init();
        createTable("table1",new String[]{"colFamily1"});
        insertData("table1","test1","colFamily1","data1","1");
        insertData("table1","test1","colFamily1","data2","2");
        insertData("table1","test1","colFamily1","data3","3");
        getTablesList();
        describeTable("table1");
        getData("table1","test1","colFamily1","data1");
        getData("table1","test1","colFamily1","data3");
        close();
    }
    /**
     * @Return void
     * @Author chenhuiyu
     * @Description 配置信息
     */
    public static void init() throws IOException {
        configuration = HBaseConfiguration.create();
        HBaseConfiguration.addHbaseResources(configuration);
//        System.setProperty("", "");
        configuration.set("hbase.root.dir", "hdfs://192.168.153.128:9000/hbase");
        configuration.set("hbase.zookeeper.quorum","192.168.153.128");
        configuration.set("hbase.zookeeper.property.clientPort","2191");

        /*......*/
        connection = ConnectionFactory.createConnection(configuration);
        admin = connection.getAdmin();
    }

    /**
     * @Return void
     * @Author chenhuiyu
     * @Description 关闭连接
     */
    public static void close() throws IOException {
        if (admin != null) {
            admin.close();
        }
        if (connection != null) {
            connection.close();
        }
    }

    /**
     * @param tableName 表名
     * @param colFamily 列族
     * @Return void
     * @Author chenhuiyu
     * @Description 创建表
     */
    public static void createTable(String tableName, String[] colFamily) throws IOException {
        TableName _tableName = TableName.valueOf(tableName);
        if (admin.tableExists(_tableName)) {
            System.out.println("表" + _tableName + "已存在");
        } else {
            //废弃
//            HTableDescriptor hTableDescriptor = new HTableDescriptor(_tableName);
//            for (String string : colFamily) {
//                HColumnDescriptor hColumnDescriptor = new HColumnDescriptor(string);
//                hTableDescriptor.addFamily(hColumnDescriptor);
//            }
//            admin.createTable(hTableDescriptor);
            TableDescriptorBuilder tableDescriptor = TableDescriptorBuilder.newBuilder(_tableName);
            List<ColumnFamilyDescriptor> columnFamilyList = new ArrayList<>();
            for (String s : colFamily) {
                ColumnFamilyDescriptor columnFamily = ColumnFamilyDescriptorBuilder.newBuilder(s.getBytes()).build();
                columnFamilyList.add(columnFamily);
            }
            TableDescriptor tableDes = tableDescriptor.setColumnFamilies(columnFamilyList).build();
            admin.createTable(tableDes);
        }
    }

    /**
     * @param tableName 表名
     * @Return void
     * @Author chenhuiyu
     * @Description 删除表
     */
    public static void deleteTable(String tableName) throws IOException {
        TableName table = TableName.valueOf(tableName);
        if (admin.tableExists(table)) {
            // 禁用表
//            admin.disableTable(table);
            admin.disableTableAsync(table);
            admin.isTableDisabled(table);
            // 删除表
            admin.deleteTable(table);
        }

    }

    /**
     * @Return void
     * @Author chenhuiyu
     * @Description 获得数据库中所有的表
     */
    public static void getTablesList() throws IOException {
//        List<String> list = new ArrayList<>();
        for (TableName table : admin.listTableNames()) {
            System.out.println(table);
        }
    }

    /**
     * @param tableName    表名
     * @param columnFamily 列族
     * @Return void
     * @Author chenhuiyu
     * @Description 向表中添加一个列族
     */
    public static void addColumnFamily(String tableName, String columnFamily) throws IOException {
        TableName table = TableName.valueOf(tableName);
        if (admin.tableExists(table)) {
//            TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(_tableName).build();
            ColumnFamilyDescriptor columnFamilyDescriptor = ColumnFamilyDescriptorBuilder.newBuilder(columnFamily.getBytes()).build();
            admin.addColumnFamily(table, columnFamilyDescriptor);
        }
    }

    /**
     * @param tableName    表名
     * @param columnFamily 列族
     * @Return void
     * @Author chenhuiyu
     * @Description 从表中移除一个列族
     */
    public static void removeColumnFamily(String tableName, String columnFamily) throws IOException {
        TableName table = TableName.valueOf(tableName);
        if (admin.tableExists(table)) {
//            TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(_tableName).build();
            admin.deleteColumnFamily(table, columnFamily.getBytes());
        }
    }

    /**
     * @param tableName 表名
     * @Return void
     * @Author chenhuiyu
     * @Description 描述表的详细信息
     */
    public static void describeTable(String tableName) throws IOException {
        TableName table = TableName.valueOf(tableName);
        if (admin.tableExists(table)) {
            ColumnFamilyDescriptor[] columnFamilyDescriptors = admin.getDescriptor(table).getColumnFamilies();
            for (ColumnFamilyDescriptor columnFamilyDescriptor : columnFamilyDescriptors) {
                System.out.println("列族名称：" + columnFamilyDescriptor.getNameAsString());
                System.out.println("文件大小：" + columnFamilyDescriptor.getBlocksize());
                System.out.println("表的配置：" + columnFamilyDescriptor.getConfigurationValue(tableName));
                System.out.println("最新版本：" + columnFamilyDescriptor.getMaxVersions());
                System.out.println("加密算法：" + columnFamilyDescriptor.getEncryptionType());
                System.out.println("生存时间：" + columnFamilyDescriptor.getTimeToLive());
                System.out.println("复制因子：" + columnFamilyDescriptor.getDFSReplication());
                System.out.println();
            }
        }
    }

    /**
     * @param tableName 表名
     * @param rowKey    行键
     * @param colFamily 列族
     * @param col       列
     * @param value     数据
     * @Return void
     * @Author chenhuiyu
     * @Description 添加数据
     */
    public static void insertData(String tableName, String rowKey, String colFamily, String col, String value) throws IOException {
        Table table = connection.getTable(TableName.valueOf(tableName));
        Put put = new Put(rowKey.getBytes());
        put.addColumn(colFamily.getBytes(), col.getBytes(), value.getBytes());
        table.put(put);
        table.close();
    }

    /**
     * @param tableName 表名
     * @param rowKey    行键
     * @Return void
     * @Author chenhuiyu
     * @Description 根据行键删除数据
     */

    public static void deleteData(String tableName, String rowKey) throws IOException {
        Table table = connection.getTable(TableName.valueOf(tableName));
        Delete delete = new Delete(rowKey.getBytes());
        table.delete(delete);
        table.close();
    }

    /**
     * @param tableName 表名
     * @param rowKey    行键
     * @param colFamily 列族
     * @param col       列
     * @Return void
     * @Author chenhuiyu
     * @Description 获取数据
     */

    public static void getData(String tableName, String rowKey, String colFamily, String col) throws IOException {
        Table table = connection.getTable(TableName.valueOf(tableName));
        Get get = new Get(rowKey.getBytes());
        get.addColumn(colFamily.getBytes(), col.getBytes());
        Result result = table.get(get);
        System.out.println(new String(result.getValue(colFamily.getBytes(), col.getBytes())));
        table.close();
    }
}
